<template>
  <div class="player" v-show="playList.length">
    <transition name="normal"
    @enter = "enter"
    @after-enter = "afterEnter"
    @leave = "leave"
    @after-leave = "afterLeave">
      <div class="normalPlayer" v-show="fullScreen">
        <div class="background">
          <img style="width:100%;height:100%" :src="currentSong.img" alt="" >
        </div>
        <div class="top">
          <div class="back" @click="back">
            <i class="icon-houtui-normal"></i>
          </div>
          <h1 class="title">{{currentSong.album}}</h1>
          <h2 class="sub">{{currentSong.singer}}</h2>
        </div>
        <div class="middle"
        @touchstart.prevent = "middleTouchStart"
        @touchmove.prevent = "middleTouchMove"
        @touchend.prevent = "middleTouchEnd">
          <div class="middle-l" ref="middleL">
            <div class="cd-wrapper" ref="cdWrapper">
              <div class="cd" :class="cdCls">
                <img class="image" style="width:100%;height:100%" :src="currentSong.img" alt="" >
              </div>
            </div>
            <div class="playing-lyric-wrapper">
              <div class="playing-lyric">{{playingLyric}}</div>
            </div>
          </div>
          <scroll class="middle-r" ref="lyricList" :data = "currentLyric && currentLyric.lines">
            <div class="lyric-wrapper">
              <div v-if="currentLyric">
                  <p ref="lyricLine" class="text" v-for="(line,index) in currentLyric.lines" 
                  :class = "{'current':index===currentLineNum}"
                  :key = "index">{{line.txt}}</p>
              </div>
            </div>
          </scroll>
        </div>
        <div class="bottom">
          <div class="dot-wrapper">
            <span class="dot" :class = "{'active' : currentShow == 'cd'}"></span>
            <span class="dot" :class = "{'active' : currentShow == 'lyric'}"></span>
          </div>
          <div class="process-wrapper">
            <span class="time time-l">{{format(currentTime)}}</span>
            <div class="process-bar-wrapper">
                <processbar :percent ="percent" @percentChange = "onPrrocessBarChange"></processbar>
            </div>
            <span class="time time-r">{{format(currentSong.duration)}}</span>
          </div>
          <div class="operators">
            <div class="icon icon-left" @click="ChangeMode">
              <i :class="iconMode"></i>
            </div>
            <div class="icon icon-left" @click="prev">
              <i class="icon-backward-normal"></i>
            </div>
            <div class="icon icon-center" @click="togglePlay">
              <i :class="playIcon" ></i>
            </div>
            <div class="icon icon-right" @click="next">
              <i class="icon-forward-normal"></i>
            </div>
            <div class="icon icon-right">
              <i class="icon-favorite-normal"></i>
            </div>
          </div>
        </div>
      </div>
    </transition>
    <transition name = "mini">
    <div class="miniPlayer" v-show="!fullScreen" @click="open">
     <div class="icon">
       <div class="imagewrapper" :class="cdCls">
         <img :src="currentSong.img"  alt="">
       </div>
     </div>
     <div class="text">
       <h2 class="name">{{currentSong.album}}</h2>
       <p class="desc">{{currentSong.singer}}</p>
     </div>
     <div class="control miniPlayControl">
       <processcircle :radius = 'radius' :percent = "percent">
         <i :class="playIcon"  class="icon-mini" @click.stop = "togglePlay"></i>
       </processcircle>
     </div>
     <div class="control PlayListControl" @click.stop = ShowFlag>
       <i class="icon-gedan-normal"></i>
     </div>
    </div>
    </transition>
    <playlist ref="playlist"></playlist>
    <audio ref = "audio" :src ="currentSong.url" @play="ready" @timeupdate = "updatetime" @ended = "end" @err = "err"></audio>
  </div>
</template>

<script>
import {mapActions, mapGetters,mapMutations} from 'vuex'
import processbar from 'base/processbar/processbar.vue'
import Processcircle from 'base/processcircle/processcircle.vue'
import animations from 'create-keyframe-animation'
import {prefixStyle} from "commom/js/dom.js"
import {playMode} from "commom/js/config.js"
import {playerMixin} from "commom/js/mixin.js"
import lyricParser from "lyric-parser"
import Scroll from 'base/scroll/scroll.vue'
import playlist from "components/playlist/playlist.vue"
const transform = prefixStyle('transform')
const transitionDuration = prefixStyle('transitionDuration')
export default {
  mixins:[playerMixin],
  data(){
    return{
      songready:false,
      radius:32,
      currentTime:0,
      currentLyric:null,
      currentLineNum:0,//当前歌词的行
      currentShow:'cd',
      playingLyric:""
    }
  },
  components: { 
    processbar,
    Processcircle,
    Scroll,
    playlist
  },

  computed:{
    playIcon(){
      return this.playing ? "icon-pause-normal" : "icon-play-normal"
    },
    cdCls(){
      return this.playing ? "play" : "play pause"
    },
    percent(){
      return (this.currentTime/this.currentSong.duration)
    },
    ...mapGetters([
      'fullScreen',
      'playing',
      'currentIndex',
    ])  
  },
  created(){
    this.touch = {};
  },
  methods:{
    ShowFlag(){//展示播放列表
      this.$refs.playlist.show()
    },
    back(){
      this.setFullScreen(false)
    },
    open(){
      this.setFullScreen(true)
    },
    prev(){
      if(!this.songready){return}
      if(this.playList.length ===1){
        this.loop();
        return
      }else{
        let index = this.currentIndex -1
        if(index === -1){
          index =this.playList.length-1
        }
        this.setCurrentIndex(index)
        if(!this.playing){
          this.togglePlay()
        }
      }     
      this.songready = false;
    },
    next(){
      if(!this.songready){return}
      if(this.playList.length === 1){
        this.loop();
        return
      }else{
        let index = this.currentIndex +1
        if(index === this.playList.length){
          index =0
        }
        this.setCurrentIndex(index)
        if(!this.playing){
          this.togglePlay();
        }
      }    
      this.songready = false;
    },
    ready(){//当歌曲准备完毕后把他写入历史数据
      this.songready = true;
      this.savePlayHistory(this.currentSong);
    },
    end(){
      console.log("end");
      if(this.playMode ===playMode.loop){
        this.loop()
      }else{
        this.next();
      }
    },
    err(){
      this.songready = true
    },
    loop(){
      this.$refs.audio.currentTime = 0;
      this.$refs.audio.play();
      if(this.currentLyric){
        this.currentLyric.seek(0);
      }
    },
    updatetime(e){
      this.currentTime =  e.target.currentTime
    },
    format(interval){
      const minutes = Math.floor(interval/60);
      const second = this._pad(Math.floor(interval%60));
      return `${minutes}:${second}`
    },
    getLyric(){//获取歌词的逻辑
      this.currentSong.getLyric().then((lyric)=>{
        this.currentLyric = new lyricParser(lyric,this.handleLyric)
        if(this.playing){
          this.currentLyric.play();
        }
      }).catch(() => {
        this.currentLyric = null
        this.playingLyric = ''
        this.currentLineNum = 0
      })
    },
    handleLyric({lineNum,txt}){
      this.currentLineNum = lineNum
      this.playingLyric = txt;
      if(lineNum > 5){
        let lineEL = this.$refs.lyricLine[lineNum-5];
        this.$refs.lyricList.scrollToElement(lineEL,1000)
      }else{
         this.$refs.lyricList.scrollTo(0,0,1000)
      }
    },
    middleTouchStart(e){
      this.touch.initiated = true;
      this.touch.move = false;
      const touch = e.touches[0];
      this.touch.startX = touch.pageX;
      this.touch.startY = touch.pageY;
    },
    middleTouchMove(e){
      if(!this.touch.initiated){
        return
      }
      let touch = e.touches[0];
      let deltaX = touch.pageX - this.touch.startX;
      let deltaY = touch.pageY - this.touch.startY;
      if(Math.abs(deltaY) > Math.abs(deltaX)){
        return;
      }
      if(!this.touch.move){
        this.touch.move = true;
      }
      const left = this.currentShow === 'cd' ? 0 :-window.innerWidth;
      const offsetWidth = Math.min(0,Math.max(-window.innerWidth,left+deltaX));
      this.touch.percent = Math.abs(offsetWidth/window.innerWidth);
      this.$refs.lyricList.$el.style[transform] =`translate3d(${offsetWidth}px,0,0)`
      this.$refs.lyricList.$el.style[transitionDuration] = 0;
      this.$refs.middleL.style.opacity = 1 - this.touch.percent
      this.$refs.middleL.style[transitionDuration] = 0
    },
    middleTouchEnd(){
      if(!this.touch.move){
        return;
      }
      let offsetWidth;
      let opacity;
      if (this.currentShow === 'cd') {
          if (this.touch.percent > 0.1) {
            offsetWidth = -window.innerWidth
            opacity = 0
            this.currentShow = 'lyric'
          } else {
            offsetWidth = 0
            opacity = 1
          }
        } else {
          if (this.touch.percent < 0.9) {
            offsetWidth = 0
            this.currentShow = 'cd'
            opacity = 1
          } else {
            offsetWidth = -window.innerWidth
            opacity = 0
          }
        }
      const time = 300;
      this.$refs.lyricList.$el.style[transform] = `translate3d(${offsetWidth}px,0,0)`;
      this.$refs.lyricList.$el.style[transitionDuration] =`${time}ms`;
      this.$refs.middleL.style.opacity = opacity;
      this.$refs.middleL.style[transitionDuration] = `${time}ms`;
      this.touch.initiated = false;
    },
    _pad(num,n=2){
      let len = num.toString().length;
      while(len < n){
        num ='0' + num;
        len++;
      }
      return num
    },
    onPrrocessBarChange(percent){
      this.currentTime = this.currentSong.duration * percent;
      this.$refs.audio.currentTime = this.currentTime;
      if(!this.playing){
        this.togglePlay()
      }
      if(this.currentLyric){
        this.currentLyric.seek(this.currentTime*1000);
      }
    },
    enter(el, done) {
      const {x, y, scale} = this._getPosAndScale()
      let animation = {
        0: {
          transform: `translate3d(${x}px,${y}px,0) scale(${scale})`
        },
        60: {
          transform: `translate3d(0,0,0) scale(1.1)`
        },
        100: {
          transform: `translate3d(0,0,0) scale(1)`
        }
      }
      animations.registerAnimation({
        name: 'move',
        animation,
        presets: {
          duration: 400,
          easing: 'linear'
        }
      })
      animations.runAnimation(this.$refs.cdWrapper, 'move', done)
    },
    afterEnter() {
      animations.unregisterAnimation('move')
      this.$refs.cdWrapper.style.animation = ''
    },
    leave(el, done) {

      this.$refs.cdWrapper.style.transition = 'all 0.4s'
      const {x, y, scale} = this._getPosAndScale()
      this.$refs.cdWrapper.style[transform] = `translate3d(${x}px,${y}px,0) scale(${scale})`
      this.$refs.cdWrapper.addEventListener('transitionend', done)
    },
    afterLeave() {
      this.$refs.cdWrapper.style.transition = '';
      this.$refs.cdWrapper.style[transform] = ''
    },
    _getPosAndScale(){
      const targetWidth = 40
      const paddingLeft = 40
      const paddingBottom = 30
      const paddingTop = 80
      const width = window.innerWidth * 0.8
      const scale = targetWidth / width
      const x = -(window.innerWidth / 2 - paddingLeft)
      const y = window.innerHeight - paddingTop - width / 2 - paddingBottom
      return {
        x,
        y,
        scale
      }
    },
    togglePlay(){
      if(!this.songready){return}
      this.setPlayingState(!this.playing);
      if(this.currentLyric){
        this.currentLyric.togglePlay();
      }
    },
    ...mapMutations({
      setFullScreen:'SET_FULL_SCREEN',
    }),
    ...mapActions([
      'savePlayHistory'
    ])
  },
  watch:{
    currentSong(newsong,oldsong){
      if (!newsong.id) {
          return
        }
      if(newsong.id === oldsong.id){
        return;
      }
      if (this.currentLyric) {
          this.currentLyric.stop()
          this.currentTime = 0
          this.playingLyric = ''
          this.currentLineNum = 0
        }
      clearTimeout(this.timer)
      this.timer = setTimeout(() => {
        this.getLyric()
        this.$refs.audio.play()    
        }, 1000)
    },
    playing(newplaying){
      let audio = this.$refs.audio;
      this.$nextTick(()=>{
         newplaying ? audio.play() : audio.pause()
      })
    }
  }
}
</script>

<style lang="stylus" scoped>
@import "~commom/stulys/variable.styl"
@import "~commom/stulys/mixin.styl"
.player
  .normalPlayer
    position :fixed;
    top:0;
    bottom :0;
    width :100%;
    background-color :$color-background;
    z-index 150
    .background
      position:absolute;
      left 0
      top 0
      bottom 0
      width 100%
      z-index -1
      opacity 0.6
      filter: blur(20px);
    .top
      position relative;
      margin-bottom 25px;
      .back
        position :absolute;
        left 6px
        top 0
        z-index 50
        .icon-houtui-normal
          display block
          padding 9px
          font-size $font-size-large-x
          transform rotate(-45deg)  
          color $color-theme
      .title
        width 70%
        text-align center
        line-height 40px
        margin 0 auto 
        color $color-text
        font-size $font-size-large
      .sub
        line-height 20px
        text-align center
        font-size $font-size-medium
        color $color-text
    .middle     
      position fixed
      top 80px
      bottom 170px
      width 100%  
      font-size 0
      white-space nowrap
      .middle-r
        display inline-block
        width 100%
        height 100%
        overflow hidden
        vertical-align: top;
        .lyric-wrapper
          width 80%
          margin 0 auto 
          text-align center
          overflow hidden
          .text
            line-height 32px
            color $color-text-l
            font-size $font-size-medium
            &.current
              color $color-theme

      .middle-l
        display inline-block
        position relative
        width 100%
        height 0
        padding-top 80%
        vertical-align: top;
        .playing-lyric-wrapper
          width 80%
          text-align center
          overflow hidden
          margin 30px auto 0 auto 
          .playing-lyric
            height: 20px
            line-height: 20px
            font-size: $font-size-medium
            color: $color-text-l
        .cd-wrapper
          width 80%
          height 100%
          position absolute
          left 10%
          top 0
          box-sizing border-box
          .cd
            height 100%
            width 100%
            border-radius 50%
            &.play
              animation rotate 20s linear infinite
            &.pause
              animation-play-state paused  
            .image
              display :block
              height 100%
              width 100%
              border-radius 50%
              box-sizing border-box
              border 10px solid rgba(255, 255, 255, 0.1)
    .bottom
      position absolute
      bottom 50px
      width 100%
      .dot-wrapper
        text-align center
        font-size 0
        .dot
          display inline-block
          height 8px
          width 8px
          border-radius 50%
          background-color rgba(255, 255, 255, 0.5)
          margin 0 4px
          &.active
            width 20px
            border-radius 5px
      .process-wrapper     
        display flex
        align-items center
        width 80%
        margin 0 auto
        padding 10px 0
        .time
          width 30px
          line-height 30px
          color $color-text
          font-size $font-size-small      
          flex 0 0 30px
          &.time-l
            text-align left 
          &.time-r
            text-align right
        .process-bar-wrapper
          flex 1
    .operators
      display flex
      align-items center
      .icon
        flex 1
        color $color-theme
        i 
          font-size 30px
      .icon-left
        text-align right 
      .icon-right
        text-align left
      .icon-center
        text-align center
        padding 0 20px
        i 
          font-size 40px 
    &.normal-enter-active, &.normal-leave-active
      transition: all 0.4s
      .top, .bottom
        transition: all 0.4s cubic-bezier(0.86, 0.18, 0.82, 1.32)
    &.normal-enter, &.normal-leave-to
      opacity: 0
      .top
        transform: translate3d(0, -100px, 0)
      .bottom
        transform: translate3d(0, 100px, 0)
  .miniPlayer
    position :fixed;
    bottom 0
    width 100%
    left 0
    background-color :$color-highlight-background
    height 60px
    display flex
    align-items center
    z-index 180
    &.mini-enter-active, &.mini-leave-active
      transition: all 0.4s
    &.mini-enter, &.mini-leave-to
      opacity: 0
    .icon
      height 40px
      width 40px
      flex 0 0 40px
      padding 0 20px 0 10px
      .imagewrapper
        width 100%
        height 100%
        &.play
          animation rotate 20s linear infinite
        &.pause
          animation-play-state paused
        img 
          display block
          width 100%
          height 100%
          border-radius 50%
    .text
      display flex
      flex-direction column
      flex 1
      line-height 20px
      justify-content center
      overflow hidden
      .name
        no-wrap()
        font-size $font-size-medium
        color $color-text
      .desc
        no-wrap()
        font-size $font-size-small
        color $color-text-d
    .control
      width 30px
      flex 0 0 30px
      padding 0 10px    
      &.miniPlayControl
        .icon-mini
          position absolute
          top 47%
          font-size: 18px
          transform translate(-50%,-50%)
        .icon-play-normal       
          left 58%
        .icon-pause-normal
          left 53%
      &.PlayListControl
        .icon-gedan-normal
          display block
          color $color-theme
          font-size 30px
@keyframes rotate 
  0%
    transform rotate(0)
  100%
    transform rotate(360deg)
</style>